#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "opcol_util.h"
#include "mbedtls/sha1.h"
#include "esp_log.h"

int OPCOL_data_piece_pop(
    char *buffer, int buffer_len,
    int *piece_start_index, int crc_len, int crc_type,
    char *data_head_mark, char *data_end_mark)
{
    int start_index=0;
    int end_marker_byte_len = strlen(data_end_mark) / 2;

    if (crc_type == 1)
    {
        start_index = OPCOL_Byte_index_of(buffer, buffer_len, data_head_mark);
        if (start_index < 0)
        {
            return 0;
        }
        int start_marker_byte_len = strlen(data_head_mark) / 2;
        unsigned char crc_byte[crc_len];
        memcpy(crc_byte, buffer + start_index + start_marker_byte_len, crc_len);
        int piece_len = 0;
        memcpy(&piece_len, crc_byte, crc_len);
        int piece_end_index = start_index + piece_len + start_marker_byte_len + crc_len;
        if (buffer_len < piece_end_index + end_marker_byte_len)
        {
            return 0;
        }
        int ei = OPCOL_Byte_index_of(buffer + piece_end_index, end_marker_byte_len, data_end_mark);
        if (ei == 0)
        {
            *piece_start_index = start_index;
            return piece_end_index - start_index + start_marker_byte_len;
        }
        //缓存区里数据错位
        return -1;
    }
    else
    {
        int end_index = OPCOL_Byte_index_of(buffer, buffer_len, data_end_mark);
        if (end_index < start_index)
        {
            return 0;
        }
        end_index = end_index + end_marker_byte_len;
        int piece_len = end_index - start_index;
        *piece_start_index = start_index;
        return piece_len;
    }
    return 0;
}

int OPCOL_Byte_index_of(char *buf, int len, char *s)
{
    int mlen = strlen(s) / 2;
    unsigned char mark_b[mlen];
    OPCOL_hex_to_char_array(s, mark_b);
    int i = 0, j = 0, ok = 0;
    for (i = 0; i < len; i++)
    {
        if ((unsigned char)buf[i] != mark_b[0])
        {
            continue;
            ok = 0;
        }
        ok = 1;
        for (j = 0; j < mlen; j++)
        {
            if ((unsigned char)buf[i + j] != mark_b[j])
            {
                ok = 0;
                break;
            }
        }
        if (ok == 1)
        {
            break;
        }
    }
    if (ok == 1)
    {
        return i;
    }
    return -1;
}

int OPCOL_String_index_of(char *buf, int len, char *s)
{
    char *f = strstr(buf, s);
    if (f == NULL)
    {
        return -1;
    }
    return f - buf;
}

void OPCOL_char_array_to_hex(unsigned char *src, int src_len, char *dest)
{
    char tmp[2];
    int i = 0;
    for (i = 0; i < src_len; i++)
    {
        sprintf(tmp, "%02X", src[i]);
        memcpy(dest + (i * 2), tmp, 2);
    }
}

int OPCOL_hex_to_char_array(char *hexstring, unsigned char *d)
{
    //ESP_LOGI("XXXX", "%s", hexstring);
    int i;
    int str_len = strlen(hexstring);
    int char_buf_len = str_len / 2;
    unsigned int uchar = 0;
    for (i = 0; i < char_buf_len; i++)
    {
        uchar = 0;
        sscanf(hexstring + 2 * i, "%2x", &uchar);
        d[i] = uchar;
    }
    return char_buf_len;
}

void SSB_sha1(unsigned char *data, int size, unsigned char hash[20])
{
    mbedtls_sha1_context sha1_ctx;
    mbedtls_sha1_init(&sha1_ctx);
    mbedtls_sha1_starts(&sha1_ctx);
    mbedtls_sha1_update(&sha1_ctx, data, size);
    mbedtls_sha1_finish(&sha1_ctx, hash);
    mbedtls_sha1_free(&sha1_ctx);
}
